#include "sfr.h"
#include "cpu.h"
#include "config.h"
#include "gpio.h"
#include "clock.h"
#include "common.h"

#include "pd.h"

#include "pwmtimer.h"
#include "xcomm.h"

#include "irinput.h"

#include "rc4.h"

#define LOG_TAG_CONST       NORM
#define LOG_TAG             "[pd]"
#include "debug.h"

int crc;
void X_crcBits(int x, int len)
{
	const int poly = 0x04C11DB6; //spec 04C1 1DB7h
	int newbit, newword, rl_crc;

	for(int i=0; i<len; i++)
	{
		newbit = ((crc>>31) ^ ((x>>i)&1)) & 1;
		if(newbit) newword=poly;
		else newword=0;
		rl_crc = (crc<<1) | newbit;
		crc = rl_crc ^ newword;
		//printf("%2d newbit=%d, x>>i=0x%x, crc=0x%x\n", i, newbit,(x>>i),crc);
	}
}
int X_crcWrap(int c)
{
	int ret = 0;
	int j, bit;

	c = ~c;
	//printf("~crc=0x%x\n", c);
	for(int i=0;i<32;i++)
	{
		j = 31-i;
		bit = (c>>i) & 1;
		ret |= bit<<j;
	}
	return ret;
}
int X_PdRecvCrc(int len)  //len--Number of Data Objects
{
    u8 i;
    crc = 0xFFFFFFFF;
    X_crcBits(Pd_Recv_Message.Header,16);
    for (i=0;i<len;i++)
    {
        X_crcBits(Pd_Recv_Message.Data[i],32);
    }

    return X_crcWrap(crc);
}
int X_PdTransCrc(int len)  //len--Number of Data Objects
{
    u8 i;
    crc = 0xFFFFFFFF;
    X_crcBits(Pd_Trans_Message.Header,16);
    for (i=0;i<len;i++)
    {
        X_crcBits(Pd_Trans_Message.Data[i],32);
    }

    return X_crcWrap(crc);
}
/*
AT_RAM
void UsbDelay(u32 us)  //150 about 7us,set to 1.5us(gap of host send continuous two packets )
{
    while (us--) {

            asm("nop");
    }
}
*/
u16 LastBitIOStatus;
AT_RAM
void X_PdTransBit0()
{
    //bit 0
    if (LastBitIOStatus)
    {
        //low for one bit period
        CC_OUTPUT_LOW;CC_OUTPUT_LOW;
        LastBitIOStatus = 0x0000;
    }
    else
    {
        //high for one bit period
        CC_OUTPUT_HIGH;CC_OUTPUT_HIGH;
        LastBitIOStatus = 0x0001;
    }
}
AT_RAM
void X_PdTransBit1()
{
    //bit1
    if (LastBitIOStatus)
    {
        //low for half bit perio
        CC_OUTPUT_LOW;
        //high for half bit period
        CC_OUTPUT_HIGH;
    }
    else
    {
        //high for half bit period
        CC_OUTPUT_HIGH;
        //low for half bit period
        CC_OUTPUT_LOW;
    }
}
AT_RAM
void X_PdTransPreamble()  //32 01,64bit
{
    u8 i;

    LastBitIOStatus = 0x0001;  //initial status

    PD_DELAYTIMER_START;
    CC_SET_TO_OUTPUT;         //switch IO to Output

    for (i=0;i<32;i++)
    {
        X_PdTransBit0();
        X_PdTransBit1();
    }
}
AT_RAM
void X_PdTransSOP()  //
{
    u8 i,j;
    for (i=0;i<4;i++)
    {
        for (j=0;j<5;j++)
        {
            if (Pd_Trans_SOP.Order[i] &0x01)  X_PdTransBit1();
            else X_PdTransBit0();
            Pd_Trans_SOP.Order[i] >>= 1;
        }
    }
}
AT_RAM
void X_PdTransEOP()  //
{
    //0D--01101 --> 10110
    X_PdTransBit1();
    X_PdTransBit0();
    X_PdTransBit1();
    X_PdTransBit1();
    X_PdTransBit0();

    X_PdTransBit0();//must transmit one bit to stop
    //switch IO to Input
    CC_SET_TO_INPUT;
    PD_DELAYTIMER_STOP;
}
AT_RAM
void X_PdTransMessage()  //
{
    u8 i,j;  //
    for (i=0;i<(4+u8TransNumberData*8+8);i++)
    {
        for (j=0;j<5;j++)
        {
            if (u8ArrayTransBuf[i] &0x01)  X_PdTransBit1();
            else X_PdTransBit0();
            u8ArrayTransBuf[i] >>= 1;
        }
    }

}
AT_RAM
void X_PdTrans()
{
    X_PdTransPreamble();
    X_PdTransSOP();
    X_PdTransMessage();
    X_PdTransEOP();
}

const u8 Pd_4B25B_Tab[] = { BMC_5B_HEX0,BMC_5B_HEX1,BMC_5B_HEX2,BMC_5B_HEX3,\
                            BMC_5B_HEX4,BMC_5B_HEX5,BMC_5B_HEX6,BMC_5B_HEX7,\
                            BMC_5B_HEX8,BMC_5B_HEX9,BMC_5B_HEXA,BMC_5B_HEXB,\
                            BMC_5B_HEXC,BMC_5B_HEXD,BMC_5B_HEXE,BMC_5B_HEXF };
u16 X_EncodePdTransData()
{
    u16 i,j;

    u8TransNumberData = 0;//((Pd_Recv_Message.Header >> 12) &0x07);

    //Header to 4bit
    for (j=0;j<4;j++)
    {
        u8ArrayTransBuf[j] = (Pd_Trans_Message.Header & 0x0F);
        Pd_Trans_Message.Header >>= 4;
    }
    //Data to 4bit
    for (i=0;i<(u8TransNumberData);i++)
    {
        for(j=0;j<8;j++)
        {
            u8ArrayTransBuf[j+4+i*8] = (Pd_Trans_Message.Data[i] & 0x0F);
            Pd_Trans_Message.Data[i] >>= 4;
        }
    }
    //Crc to 4bit
    for(j=0;j<8;j++)
    {
        u8ArrayTransBuf[j+4+u8TransNumberData*8] = (Pd_Trans_Message.Crc & 0x0F);
        Pd_Trans_Message.Crc >>= 4;
    }

    //4B -- >5B
    for(i=0;i<(4+u8TransNumberData*8+8);i++)
    {
        u8ArrayTransBuf[i] = Pd_4B25B_Tab[u8ArrayTransBuf[i]];
    }

    return (4+u8TransNumberData*8+8);
}

u16 X_DecodePdRecvData()
{
    u16 i;
    u8 u8MessageHeaderNumberData;

    u16 u16Temp0,u16Temp1,u16Temp2;
    u32 u32Temp;
    u8 j,k;

    for (i=0;i<u16PdCapCounter;i++)
    {
        if (u16ArrayPdCapData[i+1] > u16ArrayPdCapData[i]) u16Temp0 = u16ArrayPdCapData[i+1]-u16ArrayPdCapData[i];
        else u16Temp0 = u16ArrayPdCapData[i+1] + (0x10000 - u16ArrayPdCapData[i]);

        u16ArrayPdCapData[i] = u16Temp0;
    }
    //PdPreamble////////////////////////////////////
    for (i=0;i<96;)  //32 '01'
    {
        if ( (u16ArrayPdCapData[i] > BMC_FULL_BIT_MIN)
            &&  (u16ArrayPdCapData[i] < BMC_FULL_BIT_MAX) )
        {
            i++;
            if ( (u16ArrayPdCapData[i] > BMC_HALF_BIT_MIN)
                &&  (u16ArrayPdCapData[i] < BMC_HALF_BIT_MAX)
                &&  (u16ArrayPdCapData[i+1] > BMC_HALF_BIT_MIN)
                &&  (u16ArrayPdCapData[i+1] < BMC_HALF_BIT_MAX) )
            {
                i=i+2;
            }
            else
            {
                //log_info("Preamble Bit1 Err");
                return i;
            }
        }
        else
        {
            //log_info("Preamble Bit0 Err");
            return i;
        }
    }
    /////////////////////////////////////////////PdPreamble

    //decode 4B/5B
    //SOP--S1 S1 S1 S2/////////////////////////////////////////
    k=0;
    for (i=96;k<4;)
    {
        u32Temp = 0x00000000;
        for (j=0;j<5;j++)
        {
            u32Temp >>= 1;
            if ( (u16ArrayPdCapData[i] > BMC_FULL_BIT_MIN)
                &&  (u16ArrayPdCapData[i] < BMC_FULL_BIT_MAX) )
            {
                i++;
            }
            else if ( (u16ArrayPdCapData[i] > BMC_HALF_BIT_MIN)
                    &&  (u16ArrayPdCapData[i] < BMC_HALF_BIT_MAX)
                    &&  (u16ArrayPdCapData[i+1] > BMC_HALF_BIT_MIN)
                    &&  (u16ArrayPdCapData[i+1] < BMC_HALF_BIT_MAX) )
            {
                i=i+2;
                u32Temp |= 0x10;
            }
            else
            {
                //log_info("SOP Bit Err");
                return i;
            }
        }

        switch(u32Temp){
            case BMC_5B_SYNC1:
                //log_info("De-Sync1 %d",i);
                //break;
            case BMC_5B_SYNC2:
                //log_info("De-Sync2 %d",i);
                //break;
            case BMC_5B_SYNC3:
                //log_info("De-Sync3 %d",i);
                //break;
                Pd_Recv_SOP.Order[k] = u32Temp;
                k++;
                break;
            default:
                //log_info("De-SYNC Err");
                return i;
                break;
        }
    }

    //log_info("SOP End: %d",i);
    //SOP,SOP',SOP'',Hard Reset,Cable Reset
    {
        if ( (Pd_Recv_SOP.Order[0]==BMC_5B_SYNC1)&&(Pd_Recv_SOP.Order[1]==BMC_5B_SYNC1)&&(Pd_Recv_SOP.Order[2]==BMC_5B_SYNC1)&&(Pd_Recv_SOP.Order[3]==BMC_5B_SYNC2) )
        {
            //log_info("De-SOP..");
        }
        else if( (Pd_Recv_SOP.Order[0]==BMC_5B_SYNC1)&&(Pd_Recv_SOP.Order[1]==BMC_5B_SYNC1)&&(Pd_Recv_SOP.Order[2]==BMC_5B_SYNC3)&&(Pd_Recv_SOP.Order[3]==BMC_5B_SYNC3) )
        {
            //log_info("De-SOP'..");
        }
        else if( (Pd_Recv_SOP.Order[0]==BMC_5B_SYNC1)&&(Pd_Recv_SOP.Order[1]==BMC_5B_SYNC3)&&(Pd_Recv_SOP.Order[2]==BMC_5B_SYNC1)&&(Pd_Recv_SOP.Order[3]==BMC_5B_SYNC3) )
        {
            //log_info("De-SOP''..");
        }
        else
        {
            //log_info("De-SOP Err..");
            return i;
        }
    }

    ///////////////////////////////////////////////////////SOF

    //Message Header -- 16bits/////////////////////////////
    k=0;
    Pd_Recv_Message.Header = 0x0000;
    for (;k<4;)
    {
        u32Temp = 0x00000000;
        for (j=0;j<5;j++)
        {
            u32Temp >>= 1;
            if ( (u16ArrayPdCapData[i] > BMC_FULL_BIT_MIN)
                &&  (u16ArrayPdCapData[i] < BMC_FULL_BIT_MAX) )
            {
                i++;
            }
            else if ( (u16ArrayPdCapData[i] > BMC_HALF_BIT_MIN)
                    &&  (u16ArrayPdCapData[i] < BMC_HALF_BIT_MAX)
                    &&  (u16ArrayPdCapData[i+1] > BMC_HALF_BIT_MIN)
                    &&  (u16ArrayPdCapData[i+1] < BMC_HALF_BIT_MAX) )
            {
                i=i+2;
                u32Temp |= 0x10;
            }
            else
            {
                //log_info("Message Header Bit Err");
                return i;
            }
        }

        switch(u32Temp)
        {
            case BMC_5B_HEX0:
                //log_info("De-0 %d",i);
                Pd_Recv_Message.Header |= (0x00 << (k*4));
                k++;
                break;
            case BMC_5B_HEX1:
                //log_info("De-1 %d",i);
                Pd_Recv_Message.Header |= (0x01 << (k*4));
                k++;
                break;
            case BMC_5B_HEX2:
                //log_info("De-2 %d",i);
                Pd_Recv_Message.Header |= (0x02 << (k*4));
                k++;
                break;
            case BMC_5B_HEX3:
                //log_info("De-3 %d",i);
                Pd_Recv_Message.Header |= (0x03 << (k*4));
                k++;
                break;
            case BMC_5B_HEX4:
                //log_info("De-4 %d",i);
                Pd_Recv_Message.Header |= (0x04 << (k*4));
                k++;
                break;
            case BMC_5B_HEX5:
                //log_info("De-5 %d",i);
                Pd_Recv_Message.Header |= (0x05 << (k*4));
                k++;
                break;
            case BMC_5B_HEX6:
                //log_info("De-6 %d",i);
                Pd_Recv_Message.Header |= (0x06 << (k*4));
                k++;
                break;
            case BMC_5B_HEX7:
                //log_info("De-7 %d",i);
                Pd_Recv_Message.Header |= (0x07 << (k*4));
                k++;
                break;
            case BMC_5B_HEX8:
                //log_info("De-8 %d",i);
                Pd_Recv_Message.Header |= (0x08 << (k*4));
                k++;
                break;
            case BMC_5B_HEX9:
                //log_info("De-9 %d",i);
                Pd_Recv_Message.Header |= (0x09 << (k*4));
                k++;
                break;
            case BMC_5B_HEXA:
                //log_info("De-A %d",i);
                Pd_Recv_Message.Header |= (0x0A << (k*4));
                k++;
                break;
            case BMC_5B_HEXB:
                //log_info("De-B %d",i);
                Pd_Recv_Message.Header |= (0x0B << (k*4));
                k++;
                break;
            case BMC_5B_HEXC:
                //log_info("De-C %d",i);
                Pd_Recv_Message.Header |= (0x0C << (k*4));
                k++;
                break;
            case BMC_5B_HEXD:
                //log_info("De-D %d",i);
                Pd_Recv_Message.Header |= (0x0D << (k*4));
                k++;
                break;
            case BMC_5B_HEXE:
                //log_info("De-E %d",i);
                Pd_Recv_Message.Header |= (0x0E << (k*4));
                k++;
                break;
            case BMC_5B_HEXF:
                //log_info("De-F %d",i);
                Pd_Recv_Message.Header |= (0x0F << (k*4));
                k++;
                break;
            default:
                log_info("De-Message Header Err");
                return i;
                break;
        }
    }
    ///////////////////////////////////Message Header
    //log_info("Message Header End: %d",i);

    //Message Header information///////////////////////////
    /*
    if (Pd_Recv_Message.Header & 0x8000)    log_info("Dont support Extened!");
    log_info("Number of Data Objects: %d",((Pd_Recv_Message.Header >> 12) &0x07));
    log_info("MessageID: %d",((Pd_Recv_Message.Header >> 9) &0x07));
    if (Pd_Recv_Message.Header & 0x0100)
    {
        log_info("Port Power Role: Source");
    }
    else
    {
        log_info("Port Power Role: Sink");
    }
    log_info( "PD Revision: %d.0",(((Pd_Recv_Message.Header >> 6) &0x03)+1) );
    if (Pd_Recv_Message.Header & 0x0020)
    {
        log_info("Port Data Role: DFP");
    }
    else
    {
        log_info("Port Data Role: UFP");
    }
    */
    //Message Type
    u8MessageHeaderNumberData = ((Pd_Recv_Message.Header >> 12) &0x07);
    if (u8MessageHeaderNumberData == 0)  //Control Message
    {
        switch(Pd_Recv_Message.Header & 0x001F)
        {
            default:
            break;
        }
    }
    else
    {
        switch(Pd_Recv_Message.Header & 0x001F)  //Data Message
        {
            case PD_MSG_DATA_SourceCapabilities:
                //log_info("Source_Capabilities");

                break;
            default:
                break;
        }
    }
    /////////////////////////////////////////Message Header information

    //Data Message -- n*32bits
    k=0;
    for (j=0;j<7;j++) Pd_Recv_Message.Data[j] = 0x00000000;
    for (;k<(u8MessageHeaderNumberData*8);)
    {
        u32Temp = 0x00000000;
        for (j=0;j<5;j++)
        {
            u32Temp >>= 1;
            if ( (u16ArrayPdCapData[i] > BMC_FULL_BIT_MIN)
                &&  (u16ArrayPdCapData[i] < BMC_FULL_BIT_MAX) )
            {
                i++;
            }
            else if ( (u16ArrayPdCapData[i] > BMC_HALF_BIT_MIN)
                    &&  (u16ArrayPdCapData[i] < BMC_HALF_BIT_MAX)
                    &&  (u16ArrayPdCapData[i+1] > BMC_HALF_BIT_MIN)
                    &&  (u16ArrayPdCapData[i+1] < BMC_HALF_BIT_MAX) )
            {
                i=i+2;
                u32Temp |= 0x10;
            }
            else
            {
                //log_info("Data Message Bit Err");
                return i;
            }
        }

        switch(u32Temp)
        {
            case BMC_5B_HEX0:
                //log_info("De-0 %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x00 << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEX1:
                //log_info("De-1 %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x01 << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEX2:
                //log_info("De-2 %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x02 << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEX3:
                //log_info("De-3 %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x03 << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEX4:
                //log_info("De-4 %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x04 << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEX5:
                //log_info("De-5 %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x05 << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEX6:
                //log_info("De-6 %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x06 << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEX7:
                //log_info("De-7 %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x07 << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEX8:
                //log_info("De-8 %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x08 << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEX9:
                //log_info("De-9 %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x09 << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEXA:
                //log_info("De-A %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x0A << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEXB:
                //log_info("De-B %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x0B << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEXC:
                //log_info("De-C %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x0C << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEXD:
                //log_info("De-D %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x0D << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEXE:
                //log_info("De-E %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x0E << ((k%8)*4));
                k++;
                break;
            case BMC_5B_HEXF:
                //log_info("De-F %d",i);
                Pd_Recv_Message.Data[k/8] |= (0x0F << ((k%8)*4));
                k++;
                break;
            default:
                //log_info("De-Data Err");
                return i;
                break;
        }
    }
    /////////////////////////////////Data Message
    //log_info("Data Message End: %d",i);

    //Crc -- 32bits
    k=0;
    Pd_Recv_Message.Crc = 0x00000000;
    for (;k<8;)
    {
        u32Temp = 0x00000000;
        for (j=0;j<5;j++)
        {
            u32Temp >>= 1;
            if ( (u16ArrayPdCapData[i] > BMC_FULL_BIT_MIN)
                &&  (u16ArrayPdCapData[i] < BMC_FULL_BIT_MAX) )
            {
                i++;
            }
            else if ( (u16ArrayPdCapData[i] > BMC_HALF_BIT_MIN)
                    &&  (u16ArrayPdCapData[i] < BMC_HALF_BIT_MAX)
                    &&  (u16ArrayPdCapData[i+1] > BMC_HALF_BIT_MIN)
                    &&  (u16ArrayPdCapData[i+1] < BMC_HALF_BIT_MAX) )
            {
                i=i+2;
                u32Temp |= 0x10;
            }
            else
            {
                //log_info("Crc Bit Err");
                return i;
            }
        }

        switch(u32Temp)
        {
            case BMC_5B_HEX0:
                //log_info("De-0 %d",i);
                Pd_Recv_Message.Crc |= (0x00 << (k*4));
                k++;
                break;
            case BMC_5B_HEX1:
                //log_info("De-1 %d",i);
                Pd_Recv_Message.Crc |= (0x01 << (k*4));
                k++;
                break;
            case BMC_5B_HEX2:
                //log_info("De-2 %d",i);
                Pd_Recv_Message.Crc |= (0x02 << (k*4));
                k++;
                break;
            case BMC_5B_HEX3:
                //log_info("De-3 %d",i);
                Pd_Recv_Message.Crc |= (0x03 << (k*4));
                k++;
                break;
            case BMC_5B_HEX4:
                //log_info("De-4 %d",i);
                Pd_Recv_Message.Crc |= (0x04 << (k*4));
                k++;
                break;
            case BMC_5B_HEX5:
                //log_info("De-5 %d",i);
                Pd_Recv_Message.Crc |= (0x05 << (k*4));
                k++;
                break;
            case BMC_5B_HEX6:
                //log_info("De-6 %d",i);
                Pd_Recv_Message.Crc |= (0x06 << (k*4));
                k++;
                break;
            case BMC_5B_HEX7:
                //log_info("De-7 %d",i);
                Pd_Recv_Message.Crc |= (0x07 << (k*4));
                k++;
                break;
            case BMC_5B_HEX8:
                //log_info("De-8 %d",i);
                Pd_Recv_Message.Crc |= (0x08 << (k*4));
                k++;
                break;
            case BMC_5B_HEX9:
                //log_info("De-9 %d",i);
                Pd_Recv_Message.Crc |= (0x09 << (k*4));
                k++;
                break;
            case BMC_5B_HEXA:
                //log_info("De-A %d",i);
                Pd_Recv_Message.Crc |= (0x0A << (k*4));
                k++;
                break;
            case BMC_5B_HEXB:
                //log_info("De-B %d",i);
                Pd_Recv_Message.Crc |= (0x0B << (k*4));
                k++;
                break;
            case BMC_5B_HEXC:
                //log_info("De-C %d",i);
                Pd_Recv_Message.Crc |= (0x0C << (k*4));
                k++;
                break;
            case BMC_5B_HEXD:
                //log_info("De-D %d",i);
                Pd_Recv_Message.Crc |= (0x0D << (k*4));
                k++;
                break;
            case BMC_5B_HEXE:
                //log_info("De-E %d",i);
                Pd_Recv_Message.Crc |= (0x0E << (k*4));
                k++;
                break;
            case BMC_5B_HEXF:
                //log_info("De-F %d",i);
                Pd_Recv_Message.Crc |= (0x0F << (k*4));
                k++;
                break;
            default:
                //log_info("De-Crc Err");
                return i;
                break;
        }
    }
    /////////////////////////////////Crc
    //log_info("Crc End: %d",i);

    //EOP///////////////////////////////////////////
    k=0;
    for (;k<1;)
    {
        u32Temp = 0x00000000;
        for (j=0;j<5;j++)
        {
            u32Temp >>= 1;
            if ( (u16ArrayPdCapData[i] > BMC_FULL_BIT_MIN)
                &&  (u16ArrayPdCapData[i] < BMC_FULL_BIT_MAX) )
            {
                i++;
            }
            else if ( (u16ArrayPdCapData[i] > BMC_HALF_BIT_MIN)
                    &&  (u16ArrayPdCapData[i] < BMC_HALF_BIT_MAX)
                    &&  (u16ArrayPdCapData[i+1] > BMC_HALF_BIT_MIN)
                    &&  (u16ArrayPdCapData[i+1] < BMC_HALF_BIT_MAX) )
            {
                i=i+2;
                u32Temp |= 0x10;
            }
            else
            {
                //log_info("EOP Bit Err");
                return i;
            }
        }
        if (u32Temp == BMC_5B_EOP)
        {
            /*
            log_info("De-EOP %d",i);
            log_info("Header: %x",Pd_Recv_Message.Header);
            for (j=0;j<((Pd_Recv_Message.Header >> 12) &0x07);j++)
                log_info("Data %d: %x",j,Pd_Recv_Message.Data[j]);
            log_info("Crc: %x",Pd_Recv_Message.Crc);
            log_info("X_PdRecvCrc :%x",X_PdRecvCrc(((Pd_Recv_Message.Header >> 12) &0x07)));
            */
            //test crc,its OK////////////////////////////
            //crc = 0xFFFFFFFF;
            //X_crcBits(0x0E47,16);
            //log_info("Crc 0E47--1959E63A: %x\n",X_crcWrap(crc));
            //crc = 0xFFFFFFFF;
            //X_crcBits(0x0F61,16);
            //log_info("Crc 0F61--AD805588: %x\n",X_crcWrap(crc));
            ////////////////////////////////////test crc
            return i;
        }
        else
        {
            //log_info("De-EOP Err");
        }
    }
    //////////////////////////////////////EOP
    //log_info("EOP End: %d",i);

    return i;
}

u16 X_DealPdRecvData()
{

    if ((Pd_Recv_Message.Header >> 12) &0x07)  //Data Meassage
    {
        switch(Pd_Recv_Message.Header & 0x001F)  //Data Message
        {
            case PD_MSG_DATA_SourceCapabilities:
                //log_info("Deal Source_Capabilities...GoodCrc");
                //SOP
                Pd_Trans_SOP.Order[0] = BMC_5B_SYNC1;
                Pd_Trans_SOP.Order[1] = BMC_5B_SYNC1;
                Pd_Trans_SOP.Order[2] = BMC_5B_SYNC1;
                Pd_Trans_SOP.Order[3] = BMC_5B_SYNC2;
                //Header
                Pd_Trans_Message.Header = 0x0000;
                //15 -- Extened
                //14:12 -- Number of Data Objects
                Pd_Trans_Message.Header |= Pd_Recv_Message.Header & 0x0E00;//Message ID
                Pd_Trans_Message.Header |= PD_MSG_HEADER_SINK;
                Pd_Trans_Message.Header |= Pd_Recv_Message.Header & 0x00C0;//PD Revision
                Pd_Trans_Message.Header |= PD_MSG_HEADER_UFP;
                Pd_Trans_Message.Header |= PD_MSG_CTRL_GoodCRC;
                //Crc
                Pd_Trans_Message.Crc = X_PdTransCrc(0);
                //EOP
                //log_info("GoodCRC Trans Header&CRC: %x,%x",Pd_Trans_Message.Header,Pd_Trans_Message.Crc);
                //log_info("5B Number: %d\n",X_EncodePdTransData());
                X_EncodePdTransData();
                X_PdTrans();
                log_info("Pd Transmit GoodCRC...\n");
                break;
            default:
                break;
        }
    }
    else  //Control Message
    {

    }

    return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
___interrupt
static void timer1_reset_cap_isr(void)
{
    JL_TMR1->CON |= BIT(6);  //clear PND interrupt flag

}

AT_RAM
___interrupt
static void timer0_pd_cap_isr(void)
{

    JL_TMR0->CON |= BIT(6);//clear PND

    //restart timer for time out
    JL_PWM->PWMCON0 &= ~PWM_PWMCON0_T2_EN;
    JL_PWM->TMR2_CNT = 0;
    JL_PWM->PWMCON0 |= PWM_PWMCON0_T2_EN;


    u16ArrayPdCapData[u16PdCapCounter] = JL_TMR0->PRD;
    u16PdCapCounter ++;

    if (u16PdCapCounter & 0x01)
    {
        DEBUG_CC_IN_HIGH;
        SFR(JL_IOMC->IOMC1, 6, 1, 0);  //0--rising edge 1-- falling edge
    }
    else
    {
        DEBUG_CC_IN_LOW;
        SFR(JL_IOMC->IOMC1, 6, 1, 1);  //0--rising edge 1-- falling edge
    }
}



void PdGpioInit()
{
    JL_PORTB->DIE |= 0x0FCF;  //Digital IO
    //JL_PORTB->DIE &= 0xFFCF;  //ADC IO PB4&PB5

    JL_PORTB->DIR |= 0x00CF;  //Digital Input IO
    gpio_set_direction(LED_PORT, 0);  //set LED to output

    //PB2&3 PB6&7
    JL_PORTB->HD0 |= 0x00CC;
    //JL_PORTB->HD1 |= 0x00CC;

    LED_ON;
    log_info("LED ON ... \n");
    LED_OFF;

    CC_INPUT_FROM_IO;

    //PdCapInit(u16PdIoStatus);
}


void PdCapInit(u16 u16Channel)
{
    if (u16Channel == CC_CHANNEL_CC1)  SFR(JL_IOMC->IOMC2, 0, 5, CC1_IN_PORT);  //IN_CH0_SEL
    else  SFR(JL_IOMC->IOMC2, 0, 5, CC2_IN_PORT);

    SFR(JL_IOMC->IOMC1, 4, 2, 1);  //Mux to timer0  1--timer0 2--timer1 3--timer2
    SFR(JL_IOMC->IOMC1, 6, 1, 1);  //0--rising edge 1-- falling edge


    JL_TMR0->CON = BIT(6);
    JL_TMR0->PRD = 0;
    JL_TMR0->CNT = 0;

    u16PdCapCounter = 0;

    JL_TMR0->CON = BIT(1);

    HWI_Install(IRQ_TIME0_IDX, (u32)timer0_pd_cap_isr, 6);
}


void X_PdInit()
{
    PdGpioInit();
    PdCapInit(u16PdIoStatus);
}

void X_PdRecvBufInit()
{
    Pd_Recv_Message.Header = 0x0000;
    Pd_Recv_Message.Data[0] = 0x00000000;
    Pd_Recv_Message.Data[1] = 0x00000000;
    Pd_Recv_Message.Data[2] = 0x00000000;
    Pd_Recv_Message.Data[3] = 0x00000000;
    Pd_Recv_Message.Data[4] = 0x00000000;
    Pd_Recv_Message.Data[5] = 0x00000000;
    Pd_Recv_Message.Data[6] = 0x00000000;
    Pd_Recv_Message.Crc = 0x00000000;
}
void X_PdTransBufInit()
{
    Pd_Trans_Message.Header = 0x0000;
    Pd_Trans_Message.Data[0] = 0x00000000;
    Pd_Trans_Message.Data[1] = 0x00000000;
    Pd_Trans_Message.Data[2] = 0x00000000;
    Pd_Trans_Message.Data[3] = 0x00000000;
    Pd_Trans_Message.Data[4] = 0x00000000;
    Pd_Trans_Message.Data[5] = 0x00000000;
    Pd_Trans_Message.Data[6] = 0x00000000;
    Pd_Trans_Message.Crc = 0x00000000;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////


extern void X_flash_write(unsigned char *wbuf,unsigned int len);
